package cz.proks.easyhelpdesk.gwt.activity;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

import cz.proks.easyhelpdesk.api.model.Helpdesk;
import cz.proks.easyhelpdesk.api.model.HelpdeskMember;
import cz.proks.easyhelpdesk.api.model.Thread;
import cz.proks.easyhelpdesk.api.model.ThreadMember;
import cz.proks.easyhelpdesk.api.model.Ticket;
import cz.proks.easyhelpdesk.api.model.User;
import cz.proks.easyhelpdesk.gwt.ClientFactory;
import cz.proks.easyhelpdesk.gwt.Globals;
import cz.proks.easyhelpdesk.gwt.activity.base.RestrictedHelpdeskActivity;
import cz.proks.easyhelpdesk.gwt.place.HelpdeskMainPlace;
import cz.proks.easyhelpdesk.gwt.place.ThreadPlace;
import cz.proks.easyhelpdesk.gwt.ui.HelpdeskMainView;
import cz.proks.easyhelpdesk.gwt.ui.base.RestrictedHelpdeskView;

public class HelpdeskMainActivity extends RestrictedHelpdeskActivity<HelpdeskMainPlace> implements HelpdeskMainView.Presenter {
    private HelpdeskMainView view;     
    private List<Ticket> tickets;
    private int currentPage;    
    
    public HelpdeskMainActivity(HelpdeskMainPlace place, ClientFactory clientFactory, PlaceHistoryMapper placeMapper) {
        super(place, clientFactory, placeMapper);
        
        view = getClientFactory().getHelpdeskMainView();
        currentPage = 0;
    }
    
    @Override
    protected RestrictedHelpdeskView getView() {        
        return view;
    }

    @Override
    protected void onPermission(AcceptsOneWidget panel, EventBus eventBus) {        
        tickets = getTickets();
        view.setPresenter(this);
        
        showTickets(currentPage);
        
        panel.setWidget(view);
    }
    
    private void showTickets(int page) {
        int ticketsByPage = view.getTicketsByPage();
        
        int startTicket = page * ticketsByPage;
        int endTicket = Math.min(tickets.size(), startTicket + ticketsByPage);                
        
        
        List<Ticket> showingTickets = tickets.subList(startTicket, endTicket);
                                        
        view.getTickets().clear();
        view.getTickets().addAll(showingTickets);
        
        view.setStartCount((long) startTicket);
        view.setEndCount((long) endTicket);
        view.setComplexCount((long) tickets.size());
        
        currentPage = page;                               
    }
      
  
    @Override
    public void showTicket(Ticket ticket) {
        getClientFactory().getPlaceController().goTo(new ThreadPlace(getPlace().getHelpdeskId(), ticket.getThreadId()));        
    }

    @Override
    public void changeHelpdesk(Helpdesk helpdesk) {
        long helpdeskId = helpdesk != null ? helpdesk.getId() : -1l;
        
        if (helpdeskId > 0)
            getClientFactory().getPlaceController().goTo(new HelpdeskMainPlace(helpdeskId));        
    }    
    
    @Override
    public void showNextTicketPage() {
        if ((currentPage + 1) * view.getTicketsByPage() >= tickets.size())
            return;
        
        showTickets(currentPage + 1);
    }
       
    @Override
    public void showPreviousTicketPage() {
        if ((currentPage - 1) * view.getTicketsByPage() < 0)
            return;
        
        showTickets(currentPage - 1);
    }

    private List<Ticket> getTickets() {
        List<Ticket> tickets = new LinkedList<Ticket>();
        
        User user = Globals.getCurrentUser();
        Helpdesk helpdesk = Globals.getCurrentHelpdesk();
        
        HelpdeskMember helpdeskMember = Globals.getHelpdeskMemberFor(helpdesk, user);
        Collection<ThreadMember> threadMembers = Globals.getThreadMemberMapFor(helpdeskMember).values();
        
        for (ThreadMember threadMember : threadMembers) {
            Thread thread = Globals.getThreadFor(threadMember);            
            tickets.add(getJoinedTicketFor(thread.getEntryTicketId(), thread.getTickets()));
        }
        
        Collections.sort(tickets, new Comparator<Ticket>() {
            @Override
            public int compare(Ticket o1, Ticket o2) {
                return -1 * o1.getCreated().compareTo(o2.getCreated());
            }
        });
        
        return tickets;
    }
    
    private Ticket getJoinedTicketFor(Long ticketId, Collection<Ticket> tickets) {
        Ticket ticket = null;
        Date updated = null;
        
        for (Ticket aTicket : tickets) {
            updated = updated == null ? aTicket.getCreated() : 
                      updated.compareTo(aTicket.getCreated()) > 0 ? updated : aTicket.getCreated();
                      
            if (aTicket.getId().equals(ticketId))
                ticket = cloneTicket(aTicket);                            
        }
        
        if (ticket != null && updated != null)
            ticket.setCreated(updated);
        
        return ticket;
    }
    
    private Ticket cloneTicket(Ticket ticket) {
        if (ticket == null)
            return null;
        
        Ticket newTicket = new Ticket();
        
        newTicket.setId(ticket.getId());
        newTicket.setOwnerId(ticket.getOwnerId());
        newTicket.setCategoryId(ticket.getCategoryId());
        newTicket.setCreated(ticket.getCreated());
        newTicket.setThreadId(ticket.getThreadId());
        newTicket.setSubject(ticket.getSubject());
        newTicket.setDescription(ticket.getDescription());
        
        return newTicket;
    }
    
}